package com.gxar.quick.ar.server.db.service;

import com.gxar.common.entity.Result;
import com.gxar.common.entity.login.UserProfile;
import com.gxar.common.utils.SnowFlakeUtils;
import com.gxar.quick.ar.server.base.common.enums.ComboConfigItemEnum;
import com.gxar.quick.ar.server.base.common.enums.ComboGradeEnum;
import com.gxar.quick.ar.server.base.common.enums.SlotStatusEnum;
import com.gxar.quick.ar.server.base.model.combo.mapper.ComboMapStruct;
import com.gxar.quick.ar.server.base.model.combo.vo.ComboConfigInfoVO;
import com.gxar.quick.ar.server.base.model.combo.vo.response.ComboListResponse;
import com.gxar.quick.ar.server.base.model.slot.vo.request.SlotBuyRequest;
import com.gxar.quick.ar.server.base.model.slot.vo.response.SlotBuyResponse;
import com.gxar.quick.ar.server.base.model.user.vo.response.UserComboResponse;
import com.gxar.quick.ar.server.db.mapper.ComboMapper;
import com.gxar.quick.ar.server.db.mapper.SlotMapper;
import com.gxar.quick.ar.server.db.mapper.UserInfoMapper;
import com.gxar.quick.ar.server.db.model.ComboEntity;
import com.gxar.quick.ar.server.db.model.SlotEntity;
import com.gxar.quick.ar.server.db.repository.SlotRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 坑位业务控制器
 *
 * @author linsy
 * @version 1.0
 * @created 2023/11/3 16:03
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SlotService {

    private final UserInfoMapper userInfoMapper;
    private final ComboMapper comboMapper;
    private final SlotMapper slotMapper;
    private final SlotRepository slotRepository;

    public SlotEntity buildSlot(Long slotId, UserProfile userProfile, Date date, Long worksId) {
        SlotEntity slotEntity = new SlotEntity();
        if (Objects.isNull(slotId)) {
            slotId = Long.valueOf(SnowFlakeUtils.getInstance().nextId());
        } else {
            Optional<SlotEntity> oldSlotEntityOptional = slotRepository.findById(slotId);
            if (oldSlotEntityOptional.isPresent()) {
                slotEntity = oldSlotEntityOptional.get();
            }
        }

        ComboEntity comboEntity = comboMapper.findByGrade(ComboGradeEnum.ORDINARY.getCode());
        ComboListResponse comboResponseList = ComboMapStruct.INSTANCE.entityToListResponse(comboEntity);
        Map<String, ComboConfigInfoVO> configInfoVoMap = comboResponseList.getConfig().stream().collect(Collectors.toMap(ComboConfigInfoVO::getItem, t -> t, (t1, t2) -> t1));
        ComboConfigInfoVO configInfoVO = configInfoVoMap.get(ComboConfigItemEnum.SLOT.getItem());
        Integer baseComboNumber = configInfoVO.getAmount();
        Integer useSlotNumber = slotMapper.slotStatistics(userProfile.getId());
        slotEntity.setId(slotId);
        slotEntity.setWorksId(worksId);
        // 如果基础套餐的坑位还未使用完，继续使用基础套餐的坑位
        if (useSlotNumber < baseComboNumber) {
            slotEntity.setComboId(comboEntity.getId());
            slotEntity.setConfig(comboEntity.getConfig());
        } else {
            UserComboResponse userComboResponse = userInfoMapper.userCombo(userProfile.getId());
            slotEntity.setComboId(Long.valueOf(userComboResponse.getComboId()));
            slotEntity.setExpireTime(userComboResponse.getComboEndTime());
            slotEntity.setConfig(userComboResponse.getConfig());
        }
        slotEntity.setUserId(userProfile.getId());
        slotEntity.setStatus(SlotStatusEnum.AVAILABLE.getCode());
        slotEntity.setCreatedAt(Objects.nonNull(slotEntity.getCreatedAt()) ? slotEntity.getCreatedAt() : date);
        slotEntity.setCreator(Objects.nonNull(slotEntity.getCreator()) ? slotEntity.getCreator() : userProfile.getMobile());
        slotEntity.setUpdatedAt(date);
        return slotEntity;
    }

    /**
     * 购买坑位
     *
     * @param userProfile    用户信息
     * @param slotBuyRequest 坑位购买请求
     * @return 响应
     */
    public Result<SlotBuyResponse> slotBuy(UserProfile userProfile, SlotBuyRequest slotBuyRequest) {
        return null;
    }

}
